﻿using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Linq.Dynamic.Core;
using System.Text;
using System.Threading.Tasks;
using Abp;
using Abp.Application.Services.Dto;
using Abp.Authorization;
using Abp.AutoMapper;
using Abp.Configuration;
using Abp.Domain.Repositories;
using Abp.Extensions;
using Abp.Linq.Extensions;
using KDS.Mes.Mes.SeatInfos.Dtos;
using KDS.Mes.Authorization;
using KDS.Mes.Dto;
using KDS.Mes.Mes.AlcCodes;
using KDS.Mes.Mes.SeatPositions;
using KDS.Mes.Mes.Colors;
using KDS.Mes.Mes.Materials;
using Abp.UI;
using KDS.Mes.Mes.Styles;
using KDS.Mes.Mes.Cartypes;

namespace KDS.Mes.Mes.SeatInfos
{
    /// <summary>
    /// 座椅配置信息服务实现
    /// </summary>
    [AbpAuthorize(AppPermissions.Pages_Bom_SeatInfos)]
    public class SeatInfoAppService : MesAppServiceBase, ISeatInfoAppService
    {
        private readonly IRepository<SeatInfo, int> _seatInfoRepository;
        private readonly ISeatInfoListExcelExporter _seatInfoListExcelExporter;
        private readonly SeatInfoManage _seatInfoManage;
        private readonly IRepository<AlcCode, int> _alcCodeRepository;
        private readonly IRepository<SeatPosition, int> _seatPositionRepository;
        private readonly IRepository<Color, int> _colorRepository;
        private readonly IRepository<Material, int> _materialRepository;
        private readonly IRepository<Style, int> _styleRepository;
        private readonly IRepository<Cartype, int> _cartypeRepository;
        /// <summary>
        /// 构造方法
        /// </summary>
        public SeatInfoAppService(
            IRepository<SeatInfo, int> seatInfoRepository,
            SeatInfoManage seatInfoManage, 
            ISeatInfoListExcelExporter seatInfoListExcelExporter,
            IRepository<AlcCode, int> alcCodeRepository,
            IRepository<SeatPosition, int> seatPositionRepository,
            IRepository<Color, int> colorRepository,
            IRepository<Material, int> materialRepository,
             IRepository<Style, int> styleRepository,
            IRepository<Cartype, int> cartypeRepository
  )
        {
            _seatInfoRepository = seatInfoRepository;
            _seatInfoManage = seatInfoManage;
            _seatInfoListExcelExporter = seatInfoListExcelExporter;
            _alcCodeRepository = alcCodeRepository;
            _seatPositionRepository = seatPositionRepository;
            _colorRepository = colorRepository;
            _materialRepository = materialRepository;
            _styleRepository = styleRepository;
            _cartypeRepository = cartypeRepository;
        }

        #region 座椅配置信息管理



        public PagedResultDto<SeatInfoListDto> GetPagedSeatInfos(GetSeatInfoInput input)
        {

            var query = from stinfo in _seatInfoRepository.GetAll().WhereIf(input.SeatPositions[0].ToString() != "0", u => input.SeatPositions.Contains(u.SeatPositionId))
                        join alc in _alcCodeRepository.GetAll().WhereIf(!input.AlcCode.IsNullOrEmpty(), u => u.ALCCode == input.AlcCode) on stinfo.AlcCodeId equals alc.Id
                        join st in _styleRepository.GetAll().WhereIf(!input.StyleId.IsNullOrEmpty(), u => u.Id.ToString() == input.StyleId) on alc.StyleId equals st.Id
                        join ct in _cartypeRepository.GetAll().WhereIf(!input.CartypeId.IsNullOrEmpty(), u => u.Id.ToString() == input.CartypeId) on st.CartypeId equals ct.Id
                        select new
                        {
                            stinfo
                        };
            //排序
            query = !string.IsNullOrEmpty(input.Sorting) ? query.OrderBy(x => x.stinfo.Id) : query.OrderByDescending(t => t.stinfo.CreationTime);
            //获取总数
            var tasksCount = query.Count();
            //默认的分页方式
            //var taskList = query.Skip(input.SkipCount).Take(input.MaxResultCount).ToList();
            //ABP提供了扩展方法PageBy分页方式
            var taskList = query.PageBy(input).ToList();

            return new PagedResultDto<SeatInfoListDto>(
             tasksCount,
             taskList.Select(item =>
             {
                 var dto = item.stinfo.MapTo<SeatInfoListDto>();
                 return dto;
             }).ToList());






            ////初步过滤
            //var query = _seatInfoRepository.GetAll();
            ////排序
            //query = !string.IsNullOrEmpty(input.Sorting) ? query.OrderBy(x => x.Id) : query.OrderByDescending(t => t.CreationTime);
            ////获取总数
            //var tasksCount = query.Count();
            ////默认的分页方式
            ////var taskList = query.Skip(input.SkipCount).Take(input.MaxResultCount).ToList();
            ////ABP提供了扩展方法PageBy分页方式
            //var taskList = query.PageBy(input).ToList();
            //return new PagedResultDto<SeatInfoListDto>(tasksCount, taskList.MapTo<List<SeatInfoListDto>>());
        }
        /// <summary>
        /// 根据查询条件获取座椅配置信息分页列表
        /// </summary>
        public async Task<PagedResultDto<SeatInfoListDto>> GetPagedSeatInfosAsync(GetSeatInfoInput input)
        {

            var query = _seatInfoRepository.GetAll();
            //TODO:根据传入的参数添加过滤条件

            var seatInfoCount = await query.CountAsync();

            var seatInfos = await query
            .OrderBy(input.Sorting)
            .PageBy(input)
            .ToListAsync();

            var seatInfoListDtos = seatInfos.MapTo<List<SeatInfoListDto>>();
            return new PagedResultDto<SeatInfoListDto>(
            seatInfoCount,
            seatInfoListDtos
            );
        }

        /// <summary>
        /// 通过Id获取座椅配置信息信息进行编辑或修改 
        /// </summary>
        public async Task<GetSeatInfoForEditOutput> GetSeatInfoForEditAsync(NullableIdDto<int> input)
        {
            var output = new GetSeatInfoForEditOutput();

            SeatInfoEditDto seatInfoEditDto;

            if (input.Id.HasValue)
            {
                var entity = await _seatInfoRepository.GetAsync(input.Id.Value);
                seatInfoEditDto = entity.MapTo<SeatInfoEditDto>();
            }
            else
            {
                seatInfoEditDto = new SeatInfoEditDto();
            }

            output.SeatInfo = seatInfoEditDto;
            output.AlcCodes = _alcCodeRepository.GetAllList()
             .Select(c => new ComboboxItemDto(c.Id.ToString(), c.ALCCode) { IsSelected = output.SeatInfo.AlcCodeId == c.Id })
             .ToList();
            output.SeatPositions = _seatPositionRepository.GetAllList()
              .Select(c => new ComboboxItemDto(c.Id.ToString(), c.SeatPositionName) { IsSelected = output.SeatInfo.SeatPositionId == c.Id })
              .ToList();
            output.Colors = _colorRepository.GetAllList()
              .Select(c => new ComboboxItemDto(c.Id.ToString(), c.ColorName) { IsSelected = output.SeatInfo.ColorId == c.Id })
              .ToList();
            output.Materials = _materialRepository.GetAllList()
            .Select(c => new ComboboxItemDto(c.Id.ToString(), c.MaterialName) { IsSelected = output.SeatInfo.MaterialId == c.Id })
            .ToList();
            output.Slide = seatInfoEditDto.Slide;
            output.HGIT = seatInfoEditDto.HGIT;
            output.LumbarSupport = seatInfoEditDto.LumbarSupport;
            output.Warmer = seatInfoEditDto.Warmer;
            output.Ventlation = seatInfoEditDto.Ventlation;
            output.SAB = seatInfoEditDto.SAB;
            output.BackPocket = seatInfoEditDto.BackPocket;
            output.SBR = seatInfoEditDto.SBR;
            output.IMS = seatInfoEditDto.IMS;
            output.OneTouch = seatInfoEditDto.OneTouch;
            return output;
        }


        /// <summary>
        /// 通过指定id获取座椅配置信息ListDto信息
        /// </summary>
        public async Task<SeatInfoListDto> GetSeatInfoByIdAsync(EntityDto<int> input)
        {
            var entity = await _seatInfoRepository.GetAsync(input.Id);

            return entity.MapTo<SeatInfoListDto>();
        }







        /// <summary>
        /// 新增或更改座椅配置信息
        /// </summary>
        public async Task CreateOrUpdateSeatInfoAsync(CreateOrUpdateSeatInfoInput input)
        {
            if (input.SeatInfoEditDto.Id.HasValue)
            {
                await UpdateSeatInfoAsync(input.SeatInfoEditDto);
            }
            else
            {
                await CreateSeatInfoAsync(input.SeatInfoEditDto);
            }
        }

        /// <summary>
        /// 新增座椅配置信息
        /// </summary>
        [AbpAuthorize(AppPermissions.Pages_Bom_SeatInfos_Create)]
        public virtual async Task<SeatInfoEditDto> CreateSeatInfoAsync(SeatInfoEditDto input)
        {
            //TODO:新增前的逻辑判断，是否允许新增
            await CheckSeatInfoIfAlreadyExists(input);
            var entity = input.MapTo<SeatInfo>();

            entity = await _seatInfoRepository.InsertAsync(entity);
            return entity.MapTo<SeatInfoEditDto>();
        }

        /// <summary>
        /// 编辑座椅配置信息
        /// </summary>
        [AbpAuthorize(AppPermissions.Pages_Bom_SeatInfos_Edit)]
        public virtual async Task UpdateSeatInfoAsync(SeatInfoEditDto input)
        {
            //TODO:更新前的逻辑判断，是否允许更新
            await CheckSeatInfoIfAlreadyExists(input);
            var entity = await _seatInfoRepository.GetAsync(input.Id.Value);
            input.MapTo(entity);

            await _seatInfoRepository.UpdateAsync(entity);
        }

        /// <summary>
        /// 删除座椅配置信息
        /// </summary>
        [AbpAuthorize(AppPermissions.Pages_Bom_SeatInfos_Delete)]
        public async Task DeleteSeatInfoAsync(EntityDto<int> input)
        {
            //TODO:删除前的逻辑判断，是否允许删除
            await _seatInfoRepository.DeleteAsync(input.Id);
        }

        /// <summary>
        /// 批量删除座椅配置信息
        /// </summary>
        [AbpAuthorize(AppPermissions.Pages_Bom_SeatInfos_Delete)]
        public async Task BatchDeleteSeatInfoAsync(List<int> input)
        {
            //TODO:批量删除前的逻辑判断，是否允许删除
            await _seatInfoRepository.DeleteAsync(s => input.Contains(s.Id));
        }

        private async Task CheckSeatInfoIfAlreadyExists(SeatInfoEditDto input)
        {
            var existingPart = await _seatInfoRepository.GetAll()
                .FirstOrDefaultAsync(l => l.AlcCodeId == input.AlcCodeId && l.SeatPositionId == input.SeatPositionId);
            if (existingPart == null)
            {
                return;
            }
            if (input.Id != null && existingPart.Id == input.Id)
            {
                return;
            }
            throw new UserFriendlyException(L("ThisSeatInfoAlreadyExists"));
        }

        #endregion


        #region 座椅配置信息的Excel导出功能


        public async Task<FileDto> GetSeatInfoToExcel()
        {
            var entities = await _seatInfoRepository.GetAll().ToListAsync();

            var dtos = entities.MapTo<List<SeatInfoListDto>>();

            var fileDto = _seatInfoListExcelExporter.ExportSeatInfoToFile(dtos);



            return fileDto;
        }


        #endregion










    }
}
